﻿using Jupiter.Infrastructure.Cache.Interfaces;
using Jupiter.Infrastructure.Domain;
using Jupiter.Infrastructure.Domain.SqlSugar;
using Jupiter.Infrastructure.Domain.SqlSugar.Basic;
using Jupiter.Infrastructure.Exceptions;
using Jupiter.Infrastructure.Mappings;
using Jupiter.Infrastructure.Permission;
using Jupiter.Infrastructure.Permission.DataPermissions;
using MediatR;
using Microsoft.Extensions.Configuration;
using Wips.AppService.Publisher.Requests;
using Wips.Domain.Models;
using Wips.Infrastructure.Model;

namespace Wips.AppService.SqlSugar.Publisher
{
    /// <summary>
    /// 子服务
    /// </summary>
    public class AgentServerRequestHandler : RequestHandlerBase<AgentServer>,
        IRequestHandler<RegisterAgentServerRequest, string>,
        IRequestHandler<UpdateAgentServerRequest, string>,
        IRequestHandler<AddOrEditAgentServerConfigRequest, string>,
        IRequestHandler<AgentRunScriptRequest, List<string>>,
        IRequestHandler<AgentSaveFileTextRequest, string>
    {
        private readonly IMapsterMapper _mapsterMapper;
        private readonly PublishMasterService _publishMasterService;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="securityContextAccessor"></param>
        /// <param name="facadeResolver"></param>
        /// <param name="cacheManager"></param>
        /// <param name="configuration"></param>
        /// <param name="dataPermission"></param>
        /// <param name="mapsterMapper"></param>
        public AgentServerRequestHandler(ISqlSugarClient dbContext, ISecurityContextAccessor securityContextAccessor,
            IFacadeResolver facadeResolver, ICacheManager cacheManager,
            IConfiguration configuration, IDataPermission? dataPermission, IMapsterMapper mapsterMapper, PublishMasterService publishMasterService) :
            base(dbContext, securityContextAccessor, facadeResolver, cacheManager, configuration, dataPermission)
        {
            _mapsterMapper = mapsterMapper;
            _publishMasterService = publishMasterService;
        }

        /// <summary>
        /// 注册子服务
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<string> Handle(RegisterAgentServerRequest request, CancellationToken cancellationToken)
        {

            var item = await Query()
                .Where(c => c.ServerKey == request.ServerKey).FirstOrDefaultAsync();
            if (item == null)
            {
                item = _mapsterMapper.MapTo<AgentServer>(request);

                await RegisterNewAsync(item);
            }
            else
            {
                item.ServerName = request.ServerName;
                item.AgentAddress = request.AgentAddress;
                RegisterDirty(item);
            }

            return item.Id!;
        }

        /// <summary>
        /// 更新基础配置
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="CoreException"></exception>
        public async Task<string> Handle(UpdateAgentServerRequest request, CancellationToken cancellationToken)
        {
            var ok = await _publishMasterService.HealthyCheckAsync(request.AgentAddress);
            if (ok.ToLower() != "ok")
            {
                throw new CoreException("请求失败！");
            }

            var item = await Query().Where(c => c.Id == request.Id).FirstOrDefaultAsync();
            if (item == null)
            {
                throw new CoreException("未找到子服务！");
            }
            item.AgentAddress = request.AgentAddress;
            RegisterDirty(item);

            return item.Id!;

        }

        /// <summary>
        /// 添加或编辑子服务配置
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<string> Handle(AddOrEditAgentServerConfigRequest request, CancellationToken cancellationToken)
        {
            var item = _mapsterMapper.MapTo<AgentServerConfig>(request);
            if (!string.IsNullOrEmpty(request.Id))
            {
                item = await Query<AgentServerConfig>().Where(c => c.Id == request.Id).FirstOrDefaultAsync();
                if (item == null)
                {
                    throw new CoreException("未找到子服务配置！");
                }
                item = _mapsterMapper.MapTo(request, item);
                RegisterDirtyObjectValue(item);
            }
            else
            {
                await RegisterNewObjectValueAsync(item);
            }
            return item.Id;
        }


        /// <summary>
        /// 命令执行脚本
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<List<string>> Handle(AgentRunScriptRequest request, CancellationToken cancellationToken)
        {

            var flow = await Query()
              .Where(c => c.Id == request.Id).FirstOrDefaultAsync();
            if (flow == null)
            {
                throw new CoreException("未找到对应发布流程数据！");
            }
            try
            {
                var commandList = request.Command.Split(';');
                var resultList = new List<string>();
                foreach (var command in commandList)
                {
                    if (!string.IsNullOrWhiteSpace(command))
                    {
                        var result = await _publishMasterService.RunScriptAsync(flow!.AgentAddress,
                            new RunScriptRequest(request.Id, UserId)
                            {
                                Command = command
                            });
                        resultList.Add(result.Data!);
                    }

                }
                return resultList;

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                throw new CoreException(ex.Message);
            }
        }

        /// <summary>
        /// 保存修改文本
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="CoreException"></exception>
        public async Task<string> Handle(AgentSaveFileTextRequest request, CancellationToken cancellationToken)
        {

            var flow = await Query()
              .Where(c => c.Id == request.Id).FirstOrDefaultAsync();
            if (flow == null)
            {
                throw new CoreException("未找到对应发布流程数据！");
            }
            try
            {
                var result = await _publishMasterService.SaveFileTextAsync(flow!.AgentAddress,
                                       new SaveFileTextRequest(request.Id, UserId)
                                       {
                                           Path = request.Path,
                                           Content = request.Content
                                       });
                return result.Data!;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                throw new CoreException(ex.Message);
            }
        }
    }
}
